//Copyright 2009 Dominik Punz
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

#ifndef java_h__131122
#define java_h__131122

#include "jniModel.h"
#undef GetMessage

class JavaHashSetClass : public JClass
{
public:
  JavaHashSetClass() : JClass("java/util/HashSet"),
    Constructor(this, "()V"),
    Add(this, "add", "(Ljava/lang/Object;)Z")
  {}

  JConstructor Constructor;
  JBooleanMethodI Add;
};

class JavaThrowableClass : public JClass
{
public:
  JavaThrowableClass() : JClass("java/lang/Throwable"),
    GetMessage(this, "getMessage", "()Ljava/lang/String;")
  {}
  JObjectMethodI GetMessage;
};

class JavaExceptionClass : public JClass
{
public:
  JavaExceptionClass() : JClass("java/lang/Exception"),
    GetCause(this, "getCause", "()Ljava/lang/Throwable;")
  {}
  JObjectMethodI GetCause;
};

class JavaClassClass : public JClass
{
public:
  JavaClassClass() : JClass("java/lang/Class"),
    ForName(this, "forName", "()Ljava/lang/Class;"),
    GetMethods(this, "getMethods", "()[Ljava/lang/reflect/Method;"),
    IsAssignableFrom(this, "isAssignableFrom", "(Ljava/lang/Class;)Z")
  {}

  JObjectMethodS ForName;
  JObjectMethodI GetMethods;
  JBooleanMethodI IsAssignableFrom;
};

class JavaMethodClass : public JClass
{
public:
  JavaMethodClass() : JClass("java/lang/reflect/Method"),
    GetName(this, "getName", "()Ljava/lang/String;"),
    GetReturnType(this, "getReturnType", "()Ljava/lang/Class;"), //generics?
    GetParameterTypes(this, "getParameterTypes", "()[Ljava/lang/Class;"), //generics?
    Invoke(this, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")
  {}
  JObjectMethodI GetName;
  JObjectMethodI GetReturnType;
  JObjectMethodI GetParameterTypes;
  JObjectMethodI Invoke;
};

class JavaObjectClass : public JClass
{
public:
  JavaObjectClass() : JClass("java/lang/Object"),
    GetClass(this, "getClass", "()Ljava/lang/Class;"),
    ToString(this, "toString", "()Ljava/lang/String;"),
    HashCode(this, "hashCode", "()I")
  {}
  JObjectMethodI GetClass;
  JObjectMethodI ToString;
  JIntMethodI HashCode;
};

class JavaIntegerClass : public JClass
{
public:
  JavaIntegerClass() : JClass("java/lang/Integer"),
    Constructor(this, "(I)V"),
    IntValue(this, "intValue", "()I")
  {
    CJniEnvironment jni;
    TYPE = (jclass) jni.Env()->GetStaticObjectField(Class(), jni.Env()->GetStaticFieldID(Class(), "TYPE", "Ljava/lang/Class;"));
  }
  JConstructor Constructor;
  JIntMethodI IntValue;
  jclass TYPE;
};

class JavaBooleanClass : public JClass
{
public:
  JavaBooleanClass() : JClass("java/lang/Boolean"),
    Constructor(this, "(Z)V"),
    BooleanValue(this, "booleanValue", "()Z")
  {
    CJniEnvironment jni;
    TYPE = (jclass) jni.Env()->GetStaticObjectField(Class(), jni.Env()->GetStaticFieldID(Class(), "TYPE", "Ljava/lang/Class;"));
  }
  JConstructor Constructor;
  JBooleanMethodI BooleanValue;
  jclass TYPE;
};

class JavaStringClass : public JClass
{
public:
  JavaStringClass() : JClass("java/lang/String")
  {}
};

class JavaVoidClass : public JClass
{
public:
  JavaVoidClass() : JClass("java/lang/Void")
  {}
};

class JavaListClass : public JClass
{
public:
  JavaListClass() : JClass("java/util/List"),
    Get(this, "get", "(I)Ljava/lang/Object;"),
    Size(this, "size", "()I")
  {}
  JObjectMethodI Get;
  JIntMethodI Size;
};

#endif // java_h__131122